#!/usr/bin/python
# coding:utf-8
import os
import requests
import json
import gzip
import uuid
import hashlib
import time
import random
import ecdsa
from tieba import tieba
from ali_share import *
from sousou_pw import Sousou


class alipan:
    # 获取任务列表
    def __init__(self, refresh_token, is_share=False, share_folders=[], is_week_task=True, is_sign=True):
        self.is_share = is_share
        self.is_week_task = is_week_task
        self.is_sign = is_sign
        self.refresh_token = refresh_token
        self.need_share_folders = share_folders
        self.drive_id = None
        self.temp_foler_id = None
        self.temp_album_id = None
        self.verify = False
        self.verify = True
        self.nick_name = ''
        self.proxies = None
        self.share_resultss = {}
        # self.proxies = {'https': 'http://127.0.0.1:8888'}
        self.header = {
            'Content-Type': 'application/json',
            'x-canary': 'client=Android,app=adrive,version=v4.1.0',
            # 'x-device-id': '0a47b029-d116-4f44-a5aa-1ce078cfa9f7',
            # 'x-signature': 'e8e8b6073ce4e72fd6d831354711f425b01bf81297d9cf02af0989dd731bebe03b85686dc1c652bc22f7abf8136c93e37d79af8f625812faea996e7af56a221700',
            'User-Agent': 'AliApp(AYSD/4.1.0) com.alicloud.databox/27803274 Channel/10005121@rimet_android_4.1.0 language/zh-CN /Android Mobile/samsung SM-G955N'}

        self.get_access_token()
        # self.get_his_share_info()

        self.bduss = 'Z1TzdTR1MyNUdRZG85eW5WdGdqcHZHeTB2QWtLenNyaFJTcUZvTm4yeGNOZlJqSVFBQUFBJCQAAAAAAAAAAAEAAAC698GkWFlMb25nenpaAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFyozGNcqMxjRW'
        self.bduss = 'luNUlsWHY2WGxmWEQ2S1Rqa3YzcmN-N3lRQVY4VlFvR0Jhfkg3a09Vd1VmQXBrSUFBQUFBJCQAAAAAAQAAAAEAAAA3h818eHlsb25nenp6enoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABTv4mMU7-Jjel'
        self.bduss = 'jQ4VFNnSTR-VERyWHBiZE5mclhjT0lLSHhub0NZWDRsb3ZVdTF5TEVUaVJQeFJrSVFBQUFBJCQAAAAAAQAAAAEAAADB1A19bG9uZ3p6WjgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJGy7GORsuxjM'
        # self.tb = tieba(self.bduss)
        # self.tb.get_favorite()
        self.upso = upyunso()
        self.sousou = Sousou('XYLongzzZ', 'Z941562l456753')

        self.daren_share = '''容量不足可加入扩容计划，参与享最高50TB容量、延期卡等福利，点此链接报名参加：[br]
[url]https://pages.aliyundrive.com/mobile-page/web/signup.html?code=a1ef499[/url][br]'''

    # 获取Token信息
    def get_access_token(self):
        url = 'https://auth.aliyundrive.com/v2/account/token'
        data = {'refresh_token': self.refresh_token,
                'grant_type': 'refresh_token'}
        html = requests.post(url, headers=self.header, data=json.dumps(
            data), proxies=self.proxies, verify=self.verify)
        if html.status_code == 200:
            json_text = json.loads(html.text)
            if not json_text is None and 'access_token' in json_text:
                print(json_text)
                print('用戶名：', json_text['user_name'], '提示名：',
                      json_text['nick_name'], '驱动ID:', json_text['default_drive_id'])
                self.access_token = json_text['access_token']
                self.refresh_token = json_text['refresh_token']
                self.drive_id = json_text['default_drive_id']
                self.user_id = json_text['user_id']
                self.user_id = "f45a43b718264cbd9699cd9248cc73a9"
                self.user_name = json_text['user_name']
                self.nick_name = json_text['nick_name']
                print(self.nick_name)
                if self.nick_name is None or self.nick_name == '':
                    self.nick_name = self.user_name.replace('*', '')
                self.device_id = hashlib.sha256(
                    self.user_id.encode('utf-8')).hexdigest()
                self.private_key = bytes.fromhex(self.device_id)
                # self.private_key = ecdsa.SigningKey.from_string(bytes.fromhex(self.device_id), curve=ecdsa.SECP256k1)

                self.header['authorization'] = self.access_token

    # 获取相册信息
    def get_albums_info(self):
        url = 'https://api.aliyundrive.com/adrive/v1/user/albums_info'
        html = requests.post(url, headers=self.header,
                             proxies=self.proxies, verify=self.verify)
        if html.status_code == 200:
            json_text = json.loads(html.text)
            if not json_text is None and 'data' in json_text:
                json_data = json_text['data']
                if 'driveId' in json_data:
                    self.album_drive_id = json_data['driveId']
                    print('相册驱动ID：', self.album_drive_id)

    # 获取temp文件夹ID
    def get_temp_dir_id(self, is_image=False):
        temp_name = '.temp'
        files = self.get_album('root') if is_image else self.get_files('root')
        if temp_name in files:
            if is_image:
                self.temp_album_id = files[temp_name]
            else:
                self.temp_foler_id = files[temp_name]
        else:
            if is_image:
                print('不存在相册，新建相册：', temp_name)
                self.temp_album_id = self.create_album(temp_name)
            else:
                print('不存在文件夹，新建文件夹：', temp_name)
                self.temp_foler_id = self.create_folder(temp_name)

        print('temp_foler_id:', self.temp_foler_id)
        print('temp_album_id:', self.temp_album_id)

    # 获取缓存分享列表
    def get_his_share_info(self):
        path = 'ali_data/'+self.nick_name+'.json'
        if not os.path.exists(path):
            self.share_resultss = {}
        else:
            with open(path, mode='r') as f:
                self.share_resultss = json.load(f)

    # 创建相册
    def create_album(self, name):
        url = 'https://api.aliyundrive.com/adrive/v1/album/create'
        data = {
            "name": name,
            "description": ""
        }
        html = requests.post(url, headers=self.header, data=json.dumps(
            data), proxies=self.proxies, verify=self.verify)
        # print(html.text)
        if html.status_code == 200:
            json_text = json.loads(html.text)
            if not json_text is None and 'album_id' in json_text:
                return json_text['album_id']

    # 创建文件夹
    def create_folder(self, name, parent_folder='root'):
        url = 'https://api.aliyundrive.com/adrive/v2/file/createWithFolders'
        data = {
            "drive_id": self.drive_id,
            "parent_file_id": parent_folder,
            "name": name,
            "check_name_mode": "refuse",
            "type": "folder"
        }
        html = requests.post(url, headers=self.header, data=json.dumps(
            data), proxies=self.proxies, verify=self.verify)
        print(html.text)
        if html.status_code == 200:
            json_text = json.loads(html.text)
            if not json_text is None and 'file_id' in json_text:
                return json_text['file_id']

    # 获取任务列表
    def get_tasks(self):
        url = 'https://member.aliyundrive.com/v1/users/task_list'
        html = requests.post(url, headers=self.header,
                             proxies=self.proxies, verify=self.verify)
        if html.status_code == 200:
            json_text = json.loads(html.text)
            if not json_text is None and 'result' in json_text:
                json_results = json_text['result']
                return json_results

    # 分享
    def share(self, file_ids):
        url = 'https://api.aliyundrive.com/adrive/v2/share_link/create'
        data = {
            "addition_data": {
                "umidtoken": self.refresh_token,
            },
            "allow_subscribe": False,
            "channel": "publicLink",
            "drive_id": self.drive_id,
            "expiration": "",
            "file_id_list": file_ids,
            "is_photo_collection": False,
            "share_pwd": "",
            "sync_to_homepage": False
        }
        html = requests.post(url, headers=self.header, data=json.dumps(
            data), proxies=self.proxies, verify=self.verify)
        # print(html.status_code, html.text)
        if html.status_code == 200 or html.status_code == 201:
            json_text = json.loads(html.text)
            if not json_text is None and 'share_url' in json_text:
                return json_text['share_url']

    # 分享文件夹
    def share_folders(self, folder_names, is_ret_str=True):
        ret_str = ''
        root_folders = self.get_files('root')
        for folder_name, folder_tick, _ in folder_names:
            print(root_folders)
            if folder_name in root_folders:
                ret_str += folder_tick + ':[br]\n'
                files = self.get_files(root_folders[folder_name])

                if not folder_name in self.share_resultss:
                    self.share_resultss[folder_name] = {}

                for file_name, file_id in files.items():
                    if not file_name in self.share_resultss[folder_name]:
                        share_url = self.share([file_id])
                        if not share_url is None:
                            self.share_resultss[folder_name][file_name] = share_url
                            ret_str += self.mkdir_share_txt(
                                file_name, share_url)
                    else:
                        ret_str += self.mkdir_share_txt(
                            file_name, self.share_resultss[folder_name][file_name])

                ret_str += '[br]\n'
        # 缓存
        if not os.path.exists('ali_data'):
            os.mkdir('ali_data')
        with open('ali_data/'+self.nick_name+'.json', mode='w+') as f:
            f.write(json.dumps(self.share_resultss))
        return ret_str if is_ret_str else self.share_resultss

    # 生成分享信息
    def mkdir_share_txt(self, file_name, share_url):
        print(file_name, share_url)
        ret_str = file_name + ':[br]\n'
        ret_str += '[url]' + share_url + '[/url][br]\n'
        return ret_str

    # 生成分享信息
    def mkdir_share_txts(self, share_infos):
        ret_str = ''
        for file_name, share_url in share_infos.items():
            ret_str += self.mkdir_share_txt(file_name, share_url)
        return ret_str

    # 签到
    def sign(self):
        url = 'https://member.aliyundrive.com/v1/activity/sign_in_list'
        data = {}
        html = requests.post(url, headers=self.header, data=json.dumps(
            data), proxies=self.proxies, verify=self.verify)
        # print(html.text)
        if html.status_code == 200:
            json_text = json.loads(html.text)
            if not json_text is None and 'result' in json_text:
                print(self.user_name, '：完成签到')
                return json_text['result']

    # 兑换
    def task_process(self, idempotent, task_id):
        url = 'https://member.aliyundrive.com/v1/users/task_process'
        data = {
            "idempotent": idempotent,
            "taskId": task_id
        }
        html = requests.post(url, headers=self.header, data=json.dumps(
            data), proxies=self.proxies, verify=self.verify)
        # print(html.text)
        if html.status_code == 200:
            json_text = json.loads(html.text)
            if not json_text is None and 'name' in json_text:
                return json_text['name'] + json_text['description']

    # 上传任务
    def rand_upload_file_to_folder(self, is_image=False):
        name = str(uuid.uuid4()) + ('.jpg' if is_image else '.txt')
        url = 'https://api.aliyundrive.com/adrive/v2/file/createWithFolders'
        data = {
            "check_name_mode": "overwrite",
            "drive_id":        self.drive_id,
            "name":            name,
            # 'root' if is_image else self.temp_dir_id
            "parent_file_id":  self.temp_foler_id,
            "part_info_list":  [{"part_number": 1}],
            "size":            4,
            "type":            "file",
            "content_hash_name": "none",
            "proof_version":    "v1"
        }

        if is_image:
            data['create_scene'] = "album_manualbackup"
        html = requests.post(url, headers=self.header, data=json.dumps(
            data), proxies=self.proxies, verify=self.verify)
        # print(html.status_code, html.text)
        if html.status_code == 201 or html.status_code == 200:
            # print(html.text)
            json_text = json.loads(html.text)
            if not json_text is None and 'part_info_list' in json_text and 'file_id' in json_text and 'upload_id' in json_text:
                file_id = json_text['file_id']
                upload_id = json_text['upload_id']
                for json_part_info in json_text['part_info_list']:
                    upload_url = json_part_info['upload_url']
                    # 开始上传数据
                    html = requests.put(
                        upload_url, data='temp', proxies=self.proxies, verify=self.verify)
                    print('开始上传数据', file_id, html.text, html.status_code)
                    # 上传完成
                    self._on_upload_complete(file_id, upload_id)
                    if is_image:
                        self.add_to_album(self.temp_album_id, file_id)

     # 上传图片到相册
    def rand_upload_image_to_album(self):
        temp_jpg_data = "FFD8FFE000104A46494600010101006000600000FFFE0014536F6674776172653A20536E697061737465FFDB0043000302020302020303030304030304050805050404050A070706080C0A0C0C0B0A0B0B0D0E12100D0E110E0B0B1016101113141515150C0F171816141812141514FFDB00430103040405040509050509140D0B0D1414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414FFC00011080001000103012200021101031101FFC4001F0000010501010101010100000000000000000102030405060708090A0BFFC400B5100002010303020403050504040000017D01020300041105122131410613516107227114328191A1082342B1C11552D1F02433627282090A161718191A25262728292A3435363738393A434445464748494A535455565758595A636465666768696A737475767778797A838485868788898A92939495969798999AA2A3A4A5A6A7A8A9AAB2B3B4B5B6B7B8B9BAC2C3C4C5C6C7C8C9CAD2D3D4D5D6D7D8D9DAE1E2E3E4E5E6E7E8E9EAF1F2F3F4F5F6F7F8F9FAFFC4001F0100030101010101010101010000000000000102030405060708090A0BFFC400B51100020102040403040705040400010277000102031104052131061241510761711322328108144291A1B1C109233352F0156272D10A162434E125F11718191A262728292A35363738393A434445464748494A535455565758595A636465666768696A737475767778797A82838485868788898A92939495969798999AA2A3A4A5A6A7A8A9AAB2B3B4B5B6B7B8B9BAC2C3C4C5C6C7C8C9CAD2D3D4D5D6D7D8D9DAE2E3E4E5E6E7E8E9EAF2F3F4F5F6F7F8F9FAFFDA000C03010002110311003F00F37A28A2BAC0FFD9"
        temp_jpg_name = str(uuid.uuid4()) + '.jpg'
        temp_jpg_size = 653

        url = 'https://api.aliyundrive.com/adrive/v1/biz/albums/file/create'
        data = {
            "check_name_mode": "auto_rename",
            'create_scene': "album_manualbackup",
            'device_name': 	"",
            "drive_id":        self.album_drive_id,
            "name":            temp_jpg_name,
            "parent_file_id":  'root',
            "part_info_list":  [{"part_number": 1}],
            # "content_hash": "993F9F6A1F2DB2896CB8A91E08D5F74CA89D45CC",
            # "content_hash_name": "sha1",
            # "proof_code":		"2wBDAQMEBAU=",
            "content_hash_name": "none",
            "proof_version":    "v1",
            "size":            temp_jpg_size,
            "type":            "file"
        }
        html = requests.post(url, headers=self.header, data=json.dumps(
            data), proxies=self.proxies, verify=self.verify)
        # print('create result：', html.status_code, html.text)
        if html.status_code == 200:
            # print(html.text)
            json_text = json.loads(html.text)
            if not json_text is None and 'file_id' in json_text and 'upload_id' in json_text:
                file_id = json_text['file_id']
                upload_id = json_text['upload_id']
                if 'part_info_list' in json_text:
                    for json_part_info in json_text['part_info_list']:
                        upload_url = json_part_info['upload_url']
                        # 开始上传数据
                        headers2 = {"Content-Type": 'image/jpeg',
                                    'Accept': 'image/webp,image/apng,image/svg+xml,image/*,*/*;q=0.8'}
                        html = requests.put(upload_url, data=bytes.fromhex(
                            temp_jpg_data), proxies=self.proxies, verify=self.verify)
                        print('开始上传数据', file_id, html.text, html.status_code)

                        # 上传完成
                        self._on_upload_complete(
                            file_id, upload_id, is_image=True)
            self.add_to_album(self.temp_album_id, file_id)

    # 添加到相册
    def add_to_album(self, album_id, file_id):
        url = 'https://api.aliyundrive.com/adrive/v1/album/add_files'
        data = {
            "album_id": album_id,
            "drive_file_list": [{
                "drive_id": self.album_drive_id,
                "file_id": file_id
            }]
        }
        html = requests.post(url, headers=self.header, data=json.dumps(
            data), proxies=self.proxies, verify=self.verify)
        print('添加到相册：', album_id, file_id, html.text, html.status_code)

    # 上传完成
    def _on_upload_complete(self, file_id, upload_id, is_image=False):
        url = 'https://api.aliyundrive.com/v2/file/complete'
        data = {
            "drive_id": self.album_drive_id if is_image else self.drive_id,
            "file_id": file_id,
            "upload_id": upload_id,
        }
        html = requests.post(url, headers=self.header, data=json.dumps(
            data), proxies=self.proxies, verify=self.verify)
        print('上传结束：', html.text, html.status_code)

    # 周任务
    def week_task(self):
        self.clear_temp_folder()
        self.clear_temp_album()
        self.rand_upload_file_to_folder()
        for i in range(15):
            # self.rand_upload_file_to_folder(is_image=True)
            self.rand_upload_image_to_album()
        print(self.user_name, '完成周任务')

    # 获取文件列表
    def get_files(self, dir_id):
        files = {}
        url = 'https://api.aliyundrive.com/v2/file/list'
        url = 'https://api.aliyundrive.com/adrive/v3/file/list'
        data = {
            "drive_id":                self.drive_id,
            "fields":                  "*",
            "image_thumbnail_process": "image/resize,w_400/format,jpeg",
            "image_url_process":       "image/resize,w_1920/format,jpeg",
            "limit":                   200,
            "marker":                  "",
            "order_by":                '',
            "order_direction":         '',
            "parent_file_id":          dir_id,
            "video_thumbnail_process": "video/snapshot,t_0,f_jpg,ar_auto,w_300",
            "url_expire_sec":          14400,
        }
        html = requests.post(url, headers=self.header, data=json.dumps(
            data), proxies=self.proxies, verify=self.verify)
        if html.status_code == 200:
            json_text = json.loads(html.text)
            if not json_text is None and 'items' in json_text:
                for item in json_text['items']:
                    files[item['name']] = item['file_id']

        print('获取文件：', files)
        return files

    # 获取相册列表
    def get_album(self, dir_id):
        files = {}
        url = 'https://api.aliyundrive.com/adrive/v1/album/list'

        data = {"limit": 20, "order_by": "created_at", "order_direction": "ASC"}
        html = requests.post(url, headers=self.header, data=json.dumps(
            data), proxies=self.proxies, verify=self.verify)
        # print(html.status_code, html.text)
        if html.status_code == 200:
            json_text = json.loads(html.text)
            if not json_text is None and 'items' in json_text:
                for item in json_text['items']:
                    files[item['name']] = item['album_id']

        print('获取相册：', files)
        return files

    # 获取相册文件
    def get_album_files(self, album_id):
        files = {}
        url = 'https://api.aliyundrive.com/adrive/v1/album/list_files'

        data = {
            "album_id": album_id,
            "image_thumbnail_process": "image/resize,w_400/format,jpeg",
            "video_thumbnail_process": "video/snapshot,t_0,f_jpg,ar_auto,w_1000",
            "image_url_process": "image/resize,w_1920/format,jpeg",
            "filter": "",
            "fields": "*",
            "limit": 20,
            "order_by": "joined_at",
            "order_direction": "DESC"
        }
        html = requests.post(url, headers=self.header, data=json.dumps(
            data), proxies=self.proxies, verify=self.verify)
        # print(html.status_code, html.text)
        if html.status_code == 200:
            json_text = json.loads(html.text)
            if not json_text is None and 'items' in json_text:
                for item in json_text['items']:
                    files[item['name']] = item['file_id']

        print('获取相册文件：', files)
        return files

    # 删除文件
    def remove(self, file_id):
        url = 'https://api.aliyundrive.com/v2/recyclebin/trash'
        data = {
            "drive_id":                self.drive_id,
            "file_id":                 file_id,
        }
        html = requests.post(url, headers=self.header, data=json.dumps(
            data), proxies=self.proxies, verify=self.verify)
        if html.status_code == 200:
            json_text = json.loads(html.text)
            print(json_text)

    # 删除相册文件
    def remove_album(self, file_id):
        url = 'https://api.aliyundrive.com/v2/batch'
        data = {
            "drive_id":                self.drive_id,
            "file_id":                 file_id,
        }

        data = {
            "requests": [{
                "body": {
                    "drive_id": self.drive_id,
                    "file_id": file_id
                },
                "headers": {
                    "Content-Type": "application/json"
                },
                "id": file_id,
                "method": "POST",
                "url": "/recyclebin/trash"
            }],
            "resource": "file"
        }
        html = requests.post(url, headers=self.header, data=json.dumps(
            data), proxies=self.proxies, verify=self.verify)
        if html.status_code == 200:
            json_text = json.loads(html.text)
            print(json_text)

    # 清理文件夹
    def clear_folder(self, dir_id):
        files = self.get_files(dir_id)
        for file_name, file_id in files.items():
            self.remove(file_id)
            print('删除文件:', file_name)

    # 清理相册
    def clear_album(self, album_id):
        files = self.get_album_files(album_id)
        for file_name, file_id in files.items():
            self.remove_album(file_id)
            print('删除相册文件:', file_name)

        # 添加所有到相册
    def add_all_to_album(self, dir_id):
        files = self.get_files(dir_id)
        for file_name, file_id in files.items():
            self.add_to_album(self.temp_album_id, file_id)
            print('添加相册:', file_name)

        # 添加temp文件夹的所有文件到相册
    def add_temp_folder_to_album(self):
        self.add_all_to_album(self.temp_foler_id)

    # 清理temp文件夹
    def clear_temp_folder(self):
        self.clear_folder(self.temp_foler_id)

    # 清理temp相册
    def clear_temp_album(self):
        self.clear_album(self.temp_album_id)

    # 完成任务
    def do_tasks(self):
        self.get_albums_info()
        self.get_temp_dir_id()
        self.get_temp_dir_id(is_image=True)
        self.clear_folder('test')
        if self.is_sign:
            self.sign()
        if self.is_share:
            for share_folder in self.need_share_folders:
                # share_results = self.share_folders([share_folder])
                # print(share_results)
                # share_results = self.daren_share + share_results[:1000]
                # with open(share_folder[0] + '_share_info.txt', 'w', encoding="utf-8") as f:
                # f .write(share_results)
                # self.tb.publish_all(share_folder[1],share_results)

                share_results = self.share_folders([share_folder], False)
                for folder_name, share_infos in share_results.items():
                    for file_name, share_url in share_infos.items():
                        self.upso.share_url(share_url)
                        self.sousou.publishs([(share_folder[2], file_name, share_url)])

            # for folder_name, share_infos in share_results.items():
            #     for file_name, share_url in share_infos.items():
            #         to_share = self.mkdir_share_txt(file_name, share_url) + self.daren_share
            #         print(self.tb.publish('', '阿里云盘', file_name+'，需要的自取', to_share))
            #         time.sleep(1)
                    # self.tb.publish('', '阿里云盘扩容', '最新最火电视剧持续更新中', share_results)
        if self.is_week_task:
            # 获取任务列表
            tasks = self.get_tasks()
            if not tasks is None:
                for task in tasks:
                    if '周任务' in task['name']:
                        # print(task)
                        if task['status'] == 'unfinished':
                            # 未完成，执行任务
                            self.week_task()
                        elif task['status'] == 'finished' and task['statusNotice'] == '兑换':
                            # 任务已完成，待兑换
                            print(self.user_name, '开始兑换：', task['name'])
                            result = self.task_process(
                                task['idempotent'], task['id'])
                            print(self.user_name, '兑换结束：',
                                  task['name'], result)
                        elif task['status'] == 'verification' and task['statusNotice'] == '兑换':
                            # 任务已完成，已兑换
                            print(self.user_name, '已经兑换', task['name'])
                        elif task['status'] == 'end':
                            # 任务已结束
                            print(self.user_name, '任务已结束', task['name'])


if __name__ == '__main__':
    # 配置清单
    with open('alipan_config.json', 'r', encoding='utf-8') as f:
        user_infos = json.load(f)

    for user_info in user_infos:
        ali = alipan(user_info['refresh_token'], user_info['is_share'],
                     user_info['share_folders'], user_info['is_week_task'], user_info['is_sign'])
        ali.do_tasks()
        user_info['refresh_token'] = ali.refresh_token

    with open('alipan_config.json', 'w', encoding='utf-8') as f:
        json.dump(user_infos, f, ensure_ascii=False, indent=4)
